#include "GLibInit.h"
#include "GEventWrapper.h"
#include "GThreadWrapper.h"

class CGThreadWrapperTest : public CGThreadWrapper
{
public:
  CGThreadWrapperTest(const gchar *threadName, gulong its=1)
  :CGThreadWrapper(threadName)
  ,m_iterations(its)
  ,m_currentIteration(0)
  {
    m_syncEvent.Create(FALSE /*TRUE*/, FALSE); /* auto reset test */
  }

  gboolean Wait(gulong milis=WAIT_INFINITE)
  {
    if(m_running)
      m_syncEvent.Wait(milis);

	return TRUE;
  }

  gboolean Reset()
  {
    m_currentIteration = 0;
	// m_syncEvent.Clear(); // auto reset test
  
    return TRUE;
  }

protected:
  virtual gboolean RunLoop()
  {
	g_print("RunLoop (%s) (%u)!\n", m_name, m_currentIteration);
    g_usleep(G_USEC_PER_SEC);

	gboolean loop = (++m_currentIteration<m_iterations);
	if(!loop)
      m_syncEvent.Set();
  
    return loop;
  }

protected:
  gulong m_iterations;
  gulong m_currentIteration;
  CGEventWrapper m_syncEvent;
};

static void TestThread1()
{
  CGThreadWrapperTest thread("TestThread1");
  thread.CreateThread();
}

static void TestThread2()
{
  CGThreadWrapperTest thread("TestThread2", 5);
  thread.CreateThread();  
}

static void TestThread3()
{
  CGThreadWrapperTest thread("TestThread3", 5);
  thread.CreateThread();
  thread.Wait();
}

static void TestThread4()
{
  CGThreadWrapperTest thread("TestThread4", 5);
  for(int i=0; i<5; i++)
  {
    thread.CreateThread();
	if(i%2)
      thread.Wait();
	thread.DestroyThread();
	thread.Reset();
  }
}

static void TestThread5()
{
  CGThreadWrapperTest thread("TestThread5", 5);
  thread.CreateThread();
  thread.Wait(2000);
}

void AddTestThread()
{
  g_test_add_func("/thread/thread1", TestThread1);
  g_test_add_func("/thread/thread2", TestThread2);
  g_test_add_func("/thread/thread3", TestThread3);
  g_test_add_func("/thread/thread4", TestThread4);
  g_test_add_func("/thread/thread5", TestThread5);
}
